package com.wandian.texas;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;

import com.wandian.texas.entity.UserInfoEntity;

/**
 * @date : 2012-9-26, 14:04:25
 * @author: long
 * @email :108232706@qq.com
 * @description: SessionObject类
 */
public class SessionObject {

	public final int id;
	private ByteBuffer RecvBuffer;
	// public int Sendbufferpos;
	private ByteBuffer SendBuffer;
	// public int Recvbufferpos;
	private int Status;// 状态,当前处于什么操作
	public byte[] cmdStatus = new byte[] { 0, 0, 0, 0, 0, 0 };
	/**
	 * 连接服务器时候的时间,为了使非法用户占用userlist,加让时间检查
	 */
	public long connectedTime;
	//如果需要做个超时未做动作检查,每次data时候更新该数据,在main里比较多久没有data了
//	public long lastDataTime;
	private boolean isuse;
	// 原子方式更新
	private AtomicBoolean hasReceiveData = new AtomicBoolean(false);// 判断该session是否有接收的数据
	private AtomicBoolean hasSendData = new AtomicBoolean(false);// 判断该session是否有发送的数据
	public Object lockReceive = new Object();// 锁住hasReceiveData
	public Object lockSend = new Object();// 锁住hasSendData
	private final Charset charset = Charset.forName("utf-8");
	private UserInfoEntity user = new UserInfoEntity();
	private final Object userLock = new Object();
	// 处理中间值
	private final ConcurrentHashMap<String, Object> attributes = new ConcurrentHashMap<String, Object>();
	// 保存sessionkey
	public SelectionKey sessionKey;
	// 地址信息
	public String ipAddress;
	// 操作session的一些事件,可以不需要，因为这个是在mainprocess里自动扫描的
	private IoHandler handler;
	/** 当前socket客户端 */
	private SocketChannel socket;
	private static int SessionUID = 0;
	public final SessionMgr processor;

	public SessionObject(SessionMgr _processor) {
		id = SessionUID++;
		this.processor = _processor;
		synchronized (this) {
			init();
		}
	}

	public final IoHandler getHandler() {
		return handler;
	}

	public final void setHandler(IoHandler handler) {
		if (handler == null) {
			return;
		}
		this.handler = handler;
	}

	public final Object getAttribute(String key) {
		return attributes.get(key);
	}

	public final void setAttribute(String key, Object value) {
		attributes.put(key, value);
	}

	public SessionObject(SessionMgr _processor, SocketChannel _socket) {
		id = SessionUID++;
		this.processor = _processor;
		synchronized (this) {
			this.socket = _socket;
			init();
		}
	}

	public boolean isConnect() {
		if (this.socket == null)
			return false;
		return this.socket.isConnected();
	}

	private void init() {
		setRecvBuffer(ByteBuffer.allocate(1024 * 10));
		setSendBuffer(ByteBuffer.allocate(1024 * 10));
		SendBuffer.order(ByteOrder.LITTLE_ENDIAN);
		RecvBuffer.order(ByteOrder.LITTLE_ENDIAN);
	}

	public SocketChannel getChannel() {
		synchronized (this) {
			return socket;
		}
	}

	public void setChannel(SocketChannel _socket) {
		synchronized (this) {
			if (this.socket != null) {
				if (this.socket.isConnected()) {
					try {
						this.socket.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
					this.socket = null;

				}
			}
			this.socket = _socket;
			if (this.socket != null)
				this.ipAddress = this.socket.socket().getInetAddress().toString().replace("/", "");// String.format("%s:%s",
																									// this.socket.socket().getInetAddress(),
																									// this.socket.socket().getPort());
		}
	}

	public boolean close() {
		return this.processor.remove(this);
	}

	@Override
	public String toString() {
		// return String.format("SessionObject{id:%s ipAddress:%s 发送缓冲剩余:%s}",
		// id, ipAddress, remaining());
		return String.format("SessionObject{user:%s}", this.user);
	}

	public String decode(ByteBuffer buffer) // 解码
	{
		CharBuffer charBuffer = charset.decode(buffer);
		return charBuffer.toString();
	}

	public ByteBuffer encode(String str) // 编码
	{
		return charset.encode(str);
	}

	public void sendData(SelectionKey key) {
		// this.socket.
	}

	public boolean isIsuse() {
		return isuse;
	}

	public void setIsuse(boolean isuse) {
		this.isuse = isuse;
	}

	public ByteBuffer getRecvBuffer() {
		synchronized (this) {
			return RecvBuffer;
		}
	}

	public void setRecvBuffer(ByteBuffer recvBuffer) {
		synchronized (this) {
			RecvBuffer = recvBuffer;
		}
	}

	public ByteBuffer getSendBuffer() {
		synchronized (this) {
			return SendBuffer;
		}
	}

	public int remaining() {
		synchronized (this) {
			return SendBuffer.remaining();
		}
	}

	public void setSendBuffer(ByteBuffer sendBuffer) {
		synchronized (this) {
			SendBuffer = sendBuffer;
		}
	}

	public int getStatus() {
		synchronized (this) {
			return Status;
		}

	}

	public void setStatus(int status) {
		synchronized (this) {
			Status = status;
		}

	}

	// <----------user
	public UserInfoEntity getUser() {
		synchronized (userLock) {
			return user;
		}

	}

	public int RoomId() {
		return this.user.roomId;
	}

	public int SeatId() {
		return this.user.seatId;
	}

	public int UserId() {
		return this.user.userId;
	}

	public String NickName() {
		return this.user.nickName;
	}

	// -user--------->
	public void setUser(UserInfoEntity user) {
		synchronized (userLock) {
			this.user = user;
		}

	}

	public AtomicBoolean getHasReceiveData() {
		return hasReceiveData;
	}

	public void setHasReceiveData(AtomicBoolean hasReceiveData) {
		this.hasReceiveData = hasReceiveData;
	}

	public AtomicBoolean getHasSendData() {
		return hasSendData;
	}

	public void setHasSendData(AtomicBoolean hasSendData) {
		this.hasSendData = hasSendData;
	}

	public String getInfo() {
		return String.format("SessionObject{user:%s}", this.user);
	}
}
